using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using DataGridViewColumnSortMode = Habanero.Faces.Base.DataGridViewColumnSortMode;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// This the control used for selecting adding and editing a DMProperty.
    /// </summary>
    public class DMPropertySelectorControl : UserControlWin, IFormControl, IBOParentChildrenSelector
    {
        private DMClass _class;
        public IControlFactory ControlFactory { get; private set; }
        private IButton _moveUpButton;
        private IButton _moveDownButton;
        public IPanel MovePositionPanel { get; private set; }
        public IGridControl GridControl { get; private set; }

//        public event EventHandler<BOEventArgs<DMProperty>> PropertySelected;

        public DMPropertySelectorControl(IControlFactory controlFactory)
        {
            if (controlFactory == null)
                throw new HabaneroArgumentException
                    ("controlFactory", "Cannot create an 'DMPropertySelectorControl' if the control factory is null");
            ControlFactory = controlFactory;
            IBusinessObjectCollection col = new BusinessObjectCollection<DMProperty>();
            GridControl = controlFactory.CreateEditableGridControl();
            GridControl.Width = 320;
            GridControl.BusinessObjectCollection = col;
            foreach (IDataGridViewColumn column in GridControl.Grid.Columns)
            {
                column.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
            this.GridControl.ConfirmDeletion = true;
            if (GridControl.Buttons["Add"] != null) GridControl.Buttons["Add"].Visible = false;
            if (GridControl.Buttons["Edit"] != null) GridControl.Buttons["Edit"].Visible = false;
            if (GridControl.Buttons["Delete"] != null) GridControl.Buttons["Delete"].Visible = false;
            if (GridControl.Buttons["Save"] != null)
            {
                //GridControl.Buttons["Save"].Width = 70;
                GridControl.Buttons["Save"].Visible = false;
            }
            if (GridControl.Buttons["Cancel"] != null) GridControl.Buttons["Cancel"].Width = 70;
            GridControl.FilterControl.Visible = true;
            GridControl.FilterControl.AddStringFilterTextBox("", "PropertyName" );
            CreateMovePositionPanel();
            BorderLayoutManager mainLayoutManager = controlFactory.CreateBorderLayoutManager(this);
            mainLayoutManager.AddControl(GridControl, BorderLayoutManager.Position.Centre);
            mainLayoutManager.AddControl(MovePositionPanel, BorderLayoutManager.Position.East);

            GridControl.BusinessObjectSelected += ((sender, e) =>
                                                       {
                                                           try
                                                           {
                                                               FirePropertySelected((DMProperty) e.BusinessObject);
                                                               EnablePKButton();
                                                               EnableUCButton();
                                                           }
                                                           catch (Exception ex)
                                                           {
                                                               GlobalRegistry.UIExceptionNotifier.Notify(ex, "",
                                                                                                         "Error ");
                                                           }
                                                       });

            this.Enabled = false;
            GridControl.Buttons.AddButton("UC", "Unique", UCButtonClickHandler);
            IButton pkButton = GridControl.Buttons.AddButton("PK", "", (sender, e) => TogglePK());
            ((ButtonWin) pkButton).Image = FMResources.PK;
            PKButton.Enabled = false;
            UCButton.Enabled = false;

        }

        private void UCButtonClickHandler(object sender, EventArgs e)
        {
            try
            {
                CreateUniqueConstraint();
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void CreateMovePositionPanel()
        {
            IPanel panel = ControlFactory.CreatePanel();
            panel.Size = new Size(40, 100);
            MovePositionPanel = ControlFactory.CreatePanel();
            MovePositionPanel.Size = new Size(40, 50);
            MovePositionPanel.MinimumSize = MovePositionPanel.Size;
            _moveUpButton = ControlFactory.CreateButton("", MoveUpClickHandler);
            ((ButtonWin)_moveUpButton).Image = FMResources.imageup;
            _moveDownButton = ControlFactory.CreateButton("", MoveDownClickHandler);
            _moveDownButton.Top = 50;
            ((ButtonWin)_moveDownButton).Image = FMResources.imagedown;
            ColumnLayoutManager layoutManager = new ColumnLayoutManager(MovePositionPanel, this.ControlFactory);
            layoutManager.AddControl(panel);
            layoutManager.AddControl(_moveUpButton);
            layoutManager.AddControl(_moveDownButton);
        }

        private void MoveUpClickHandler(object sender, EventArgs e)
        {
            try
            {
                if (this.Class == null) return;
                ClearFilterSortGrid();
                this.Class.MovePropertyUp(this.SelectedProperty);
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void MoveDownClickHandler(object sender, EventArgs e)
        {
            try
            {
                if (this.Class == null) return;
                ClearFilterSortGrid();
                this.Class.MovePropertyDown(this.SelectedProperty);
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void ClearFilterSortGrid()
        {
            try
            {
                DMProperty selectedProperty = this.SelectedProperty;
                this.GridControl.FilterControl.ClearFilters();
                this.GridControl.Grid.Sort("OrdinalPosition", true);
                this.SelectedProperty = selectedProperty;
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        public IButton PKButton
        {
            get { return this.GridControl.Buttons["PK"]; }
        }

        private IButton UCButton
        {
            get { return this.GridControl.Buttons["UC"]; }
        }


        public DMProperty SelectedProperty
        {
            get { return (DMProperty) GridControl.SelectedBusinessObject; }
            set { GridControl.SelectedBusinessObject = value; }
        }

        public DMClass Class
        {
            get { return _class; }
            set
            {
                try
                {
                    _class = value;
                    if (_class != null)
                    {
                        this.Enabled = true;
                        GridControl.BusinessObjectCollection = _class.Properties;
                    }
                    else
                    {
                        this.Enabled = false;
                        GridControl.BusinessObjectCollection = null; // new BusinessObjectCollection<DMProperty>();
                        GridControl.SelectedBusinessObject = null;
                    }
                    EnablePKButton();
                    EnableUCButton();
                }
                catch (Exception ex)
                {
                    GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
                }
            }
        }

        public BusinessObjectCollection<DMProperty> Properties
        {
            get { return (BusinessObjectCollection<DMProperty>) GridControl.BusinessObjectCollection; }
        }

        private void FirePropertySelected(DMProperty dmProperty)
        {
//            if (this.PropertySelected != null)
//            {
//                this.PropertySelected(this, new BOEventArgs<DMProperty>(dmProperty));
//            }
            if (this.BusinessObjectSelected != null)
            {
                this.BusinessObjectSelected(this, new BOEventArgs(dmProperty));
            }
        }

        public void SetForm(IFormHabanero form)
        {
        }

        IBusinessObject IBusinessObjectControl.BusinessObject
        {
            get { return Class; }
            set { Class = (DMClass) value; }
        }

        #region IBOColSelector

        public event EventHandler<BOEventArgs> BusinessObjectSelected;

        public void Clear()
        {
            this.GridControl.Clear();
        }

        public IBusinessObject GetBusinessObjectAtRow(int row)
        {
            return this.GridControl.GetBusinessObjectAtRow(row);
        }

        public IBusinessObjectCollection BusinessObjectCollection
        {
            get { return this.GridControl.BusinessObjectCollection; }
            set { this.GridControl.BusinessObjectCollection = value; }
        }

        public IBusinessObject SelectedBusinessObject
        {
            get { return this.GridControl.SelectedBusinessObject; }
            set { this.GridControl.SelectedBusinessObject = value; }
        }

        public int NoOfItems
        {
            get { return this.GridControl.NoOfItems; }
        }

        /// <summary>
        ///             Gets and sets whether this selector autoselects the first item or not when a new collection is set.
        /// </summary>
        public bool AutoSelectFirstItem
        {
            get { return GridControl.AutoSelectFirstItem; }
            set { GridControl.AutoSelectFirstItem = value; }
        }

        #endregion

        /// <summary>
        /// Toggles the primary key flag for the currently selected <see cref="DMProperty"/>s.
        /// </summary>
        public void TogglePK()
        {
            try
            {
                if (this.Class == null) return;
                if (this.Class.Generated.GetValueOrDefault())
                {
                    throw new UserException("The primary key cannot be changed as the entity '" + this.Class.ToString() + "' has already been exported.");
                }
                IList<BusinessObject> selectedBusinessObjects = GridControl.Grid.SelectedBusinessObjects;
                IList<DMProperty> listProperties = selectedBusinessObjects.Cast<DMProperty>().ToList();
                DMObjectIdentity objectIdentity = this.Class.ObjectIdentity;
                if (objectIdentity == null)
                {
                    this.Class.SetObjectIdentity(listProperties);
                    return;
                }
                if (!objectIdentity.ArePropertiesEqual(listProperties))
                {
                    this.Class.SetObjectIdentity(listProperties);
                }
                else
                {
                    this.Class.SetObjectIdentity(new List<DMProperty>());
                }
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void EnablePKButton()
        {
            IButton pkButton = this.GridControl.Buttons["PK"];
            if (pkButton == null)
            {
                const string message =
                    "The PK Button cannot be enabled or disabled since the PK button has been removed";
                throw new HabaneroDeveloperException(message, message);
            }
            if (this.Class !=null && this.Class.Generated.GetValueOrDefault())
            {
                pkButton.Enabled = false;
            }
            else
            {
                pkButton.Enabled = this.SelectedBusinessObject != null;
            }
        }

        private void EnableUCButton()
        {
            IButton ucButton = this.UCButton;
            if (ucButton == null)
            {
                const string message =
                    "The UC Button cannot be enabled or disabled since the UC button has been removed";
                throw new HabaneroDeveloperException(message, message);
            }
            ucButton.Enabled = this.SelectedBusinessObject != null;
        }

        internal DMUniqueConstraint CreateUniqueConstraint()
        {

            if (this.Class == null) return null;
            IList<DMProperty> selectedProperties = this.GridControl.Grid.SelectedBusinessObjects.Cast<DMProperty>().ToList();
            DMUniqueConstraint uniqueConstraint = this.Class.CreateUnsavedUniqueConstraint(selectedProperties);
            return uniqueConstraint;

        }

        //private void SetUpGrid()
        //{
        //    IGridBase grid = this.GridControl.Grid;
        //    grid.ClassDef = ClassDef.ClassDefs[typeof(DMProperty)];
        //    string idColumnName = grid.IDColumnName;
        //    int addedColIndex = grid.Columns.Add(idColumnName, idColumnName);
        //    IDataGridViewColumn gvColumn = grid.Columns[addedColIndex];
        //    gvColumn.DataPropertyName = idColumnName;
        //    gvColumn.Visible = false;
        //    SetUpGridColumns();
        //    grid.GridLoader = GridLoaderDelegate;
        //}

        //private void GridLoaderDelegate(IGridBase grid, IBusinessObjectCollection col)
        //{
        //    grid.Rows.Clear();
        //    if (col == null) return;

        //    foreach (IBusinessObject businessObject in col)
        //    {
        //        DMProperty dmProperty = (DMProperty)businessObject;
        //        Image image;
        //        if (dmProperty.IsPartOfObjectIdentity)
        //        {
        //            image = FMResources.PK;
        //        }
        //        else
        //        {
        //            image = FMResources.Empty;
        //        }
        //        grid.Rows.Add(dmProperty.ID, image, dmProperty.PropertyName, dmProperty.OrdinalPosition);
        //    }
        //}

        //private void SetUpGridColumns()
        //{
        //    IGridBase grid = this.GridControl.Grid;
        //    IDataGridViewImageColumn gvImageColumn = GlobalUIRegistry.ControlFactory.CreateDataGridViewImageColumn();
        //    gvImageColumn.Name = "PK";
        //    gvImageColumn.Width = 20;
        //    grid.Columns.Add(gvImageColumn);
        //    grid.Columns.Add("PropertyName", "PropertyName");
        //    grid.Columns.Add("OrdinalPosition", "Order");
        //   // grid.Columns["OrdinalPosition"].Visible = false;
        //    //foreach (IDataGridViewColumn column in grid.Columns)
        //    //{
        //    //    column.SortMode = DataGridViewColumnSortMode.NotSortable;
        //    //}
        //}

        //private void SetColumnImage()
        //{
        //    IGridBase grid = this.GridControl.Grid;
        //    for (int count = 0; count < grid.Rows.Count-1; count++)
        //    {
        //        DMProperty dmProperty = (DMProperty) this.GridControl.GetBusinessObjectAtRow(count);
        //        IDataGridViewCell cell = grid.Rows[count].Cells["-IsPartOfObjectIdentity-"];
        //        if (dmProperty.IsPartOfObjectIdentity)
        //        {
                    
        //            cell.Value = FMResources.PK;
                    
        //            //DataGridViewWin.DataGridViewRowWin dataGridViewRow = (DataGridViewWin.DataGridViewRowWin) grid.Rows[count];
        //            ////dataGridViewRow.DataGridViewRow.HeaderCell.Value = "W";
        //        }
        //        else
        //        {
        //            cell.Value = FMResources.Empty;
        //        }
                 
        //    }
        //}
    }
}